package me.kuye.jkuye.core;

import java.util.List;

import javax.servlet.ServletContext;

import me.kuye.jkuye.config.Constants;
import me.kuye.jkuye.config.JKuyeConfig;
import me.kuye.jkuye.handler.Handler;
import me.kuye.jkuye.handler.HandlerFactory;
import me.kuye.jkuye.helper.PathHelper;
import me.kuye.jkuye.plugin.IPlugin;
import me.kuye.jkuye.render.RenderFactory;
import me.kuye.jkuye.token.ITokenCache;
import me.kuye.jkuye.token.TokenManager;
import me.kuye.jkuye.upload.OreillyCos;

public final class JKuye {
	private static final JKuye instance = new JKuye();
	private ServletContext servletContext;
	private String contextPath;
	private Constants constants;
	private ActionMapping actionMapping;
	private Handler handler;

	private JKuye() {
	}

	public static JKuye getInstance() {
		return instance;
	}

	public boolean init(JKuyeConfig jKuyeConfig, ServletContext servletContext) {
		this.servletContext = servletContext;
		this.contextPath = servletContext.getContextPath();

		initPathUtil();
		Config.init(jKuyeConfig);
		initActionMapping();
		initHandler();
		initRender();
		initOreillyCos();// http 上传文件组件
		initTokenManager();
		return true;
	}

	private void initTokenManager() {
		ITokenCache tokenCache = constants.getTokenCache();
		if (tokenCache != null) {
			TokenManager.init(tokenCache);
		}
	}

	private void initOreillyCos() {
		OreillyCos.init(constants.getUploadedFileSaveDirectory(), constants.getMaxPostSize(), constants.getEncoding());
	}

	private void initRender() {
		RenderFactory renderFactory = RenderFactory.getInstance();
		renderFactory.init(servletContext, constants);
	}

	private void initHandler() {
		Handler actionHandler = new ActionHandler(actionMapping, constants);
		handler = HandlerFactory.getHandler(Config.getHandlers().getHandlerList(), actionHandler);
	}

	private void initActionMapping() {
		actionMapping = new ActionMapping(Config.getRoutes(), Config.getInterceptors());
		actionMapping.buildActionMapping();
	}

	private void initPathUtil() {
		String path = servletContext.getRealPath("/");
		PathHelper.setWebRootPath(path);
	}

	public void stopPlugins() {
		List<IPlugin> pluginList = Config.getPlugins().getPluginList();
		if (pluginList != null) {
			for (int i = pluginList.size() - 1; i > 0; i--) {
				boolean success = false;
				try {
					success = pluginList.get(i).destory();
				} catch (Exception e) {
					success = false;
					e.printStackTrace();
				}
				if (!success) {
					System.err.println("Plugin stop error: " + pluginList.get(i).getClass().getName());
				}
			}
		}
	}

	/**
	 * @return the servletContext
	 */
	public ServletContext getServletContext() {
		return servletContext;
	}

	/**
	 * @return the contextPath
	 */
	public String getContextPath() {
		return contextPath;
	}

	/**
	 * @return the constants
	 */
	public Constants getConstants() {
		return constants;
	}

	/**
	 * @return the actionMapping
	 */
	public ActionMapping getActionMapping() {
		return actionMapping;
	}

	/**
	 * @return the handler
	 */
	public Handler getHandler() {
		return handler;
	}

}
